/*
    File:       TCPListenerSocket.cpp

    Contains:   implements TCPListenerSocket class
                    
    
*/

#ifndef __Win32__
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <unistd.h>
#endif

#include <errno.h>
#include "OS.h"
#include "OSThread.h"
#include "TCPListenerSocket.h"

OS_Error TCPListenerSocket::Listen(UInt32 queueLength)
{
    if (fFileDesc == kInvalidFileDesc)
        return EBADF;
        
    int err = ::listen(fFileDesc, queueLength);
    if (err != 0)
        return (OS_Error)OS::GetErrno();
    return OS_NoErr;
}

OS_Error TCPListenerSocket::Initialize(UInt32 addr, UInt16 port)
{
    OS_Error err = this->TCPSocket::Open();
    if (0 == err) do
    {   
        // set SO_REUSEADDR socket option before calling bind.
#ifndef __Win32__
        // this causes problems on NT (multiple processes can bind simultaneously),
        // so don't do it on NT.
        this->ReuseAddr();
#endif
        err = this->Bind(addr, port);
        if (err != 0) break; // don't assert this is just a port already in use.

        //
        // Unfortunately we need to advertise a big buffer because our TCP sockets
        // can be used for incoming broadcast data. This could force the server
        // to run out of memory faster if it gets bogged down, but it is unavoidable.
        this->SetSocketRcvBufSize(32 * 1024);       
        err = this->Listen(kListenQueueLength);
        Assert(err == 0);
        if (err != 0) break;
        
    } while (false);
    
    return err;
}

